﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.Data;
using System.Windows.Media.Imaging;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Controls;
using System.Globalization;
using produccion.modelo;
using produccion.AccesoDatos;
using produccion.clases;
using System.Windows.Input;
using System.Collections.Specialized;

namespace produccion.vistamodelo
{
    class VMReporteNovedadesPesos : ViewModelBase, IDataErrorInfo 
    {
        #region Campos

            private CLSSEMANAS _semana = new CLSSEMANAS();
            private List<CLSMAEEMPP> _empleados = new List<CLSMAEEMPP>();
            private CLSMAEEMPP _selempleado = new CLSMAEEMPP();
            private List<CLSPRCPRD> _procesos = new List<CLSPRCPRD>();
            private CLSPRCPRD _selproceso = new CLSPRCPRD();

            private List<CLSNOVPRD> _lisnovedad = new List<CLSNOVPRD>();
            
            private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();

        #endregion

        #region Constructor
            public VMReporteNovedadesPesos()
            {
                try
                {
                    consultarProcesos();
                    lisnovedades.CollectionChanged +=OnCollectionChanged;
                    if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                    {
                        MDOgeneral.conectar();
                    }
                    strTituloVentana = "Reporte de novedades en pesos" + " - Usuario: " + MDOgeneral.usuario + " - [FRMReporteNovedadesPesos]";

                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }
        #endregion

        #region Interfaces publicas
   
            public int semana
            {
                get { return _semana.NROSEM_SEM; }
                set 
                {
                    _semana.NROSEM_SEM = value;
                    consultarSemana("S");
                    consultarEmpleados();
                    consultarNovedad();
                    base.OnPropertyChanged("semana"); 
                }
            }

            public DateTime dtmDesde
            {
                get { return _semana.DESDE_SEM; }
                set { _semana.DESDE_SEM = value; base.OnPropertyChanged("dtmDesde"); }
            }

            public DateTime dtmHasta
            {
                get { return _semana.HASTA_SEM; }
                set 
                {
                    _semana.HASTA_SEM = value;
                    consultarSemana("F");
                    base.OnPropertyChanged("dtmHasta"); 
                }
            }

            private Int32 _numConsecutivo = 0;
            public Int32 numConsecutivo
            {
                get { return _numConsecutivo; }
                set { _numConsecutivo = value; base.OnPropertyChanged("numConsecutivo"); }
            }

            public List<CLSMAEEMPP> empleados
            {
                get { return _empleados; }
                set { _empleados = value; base.OnPropertyChanged("empleados"); }
            }

            public CLSMAEEMPP selempleado
            {
                get { return _selempleado; }
                set { 
                        _selempleado = value;
                        if (_selempleado != null && _selproceso != null)
                        {
                            consultarNovedad();
                        }
                        base.OnPropertyChanged("selempleado"); 
                    }
            }

            public List<CLSPRCPRD> procesos
            {
                get { return _procesos;}
                set { _procesos=value; base.OnPropertyChanged("procesos");}
            }

            public CLSPRCPRD selproceso
            {
                get { return _selproceso; }
                set 
                { 
                    _selproceso = value;
                    consultarNovedad();
                    base.OnPropertyChanged("selproceso"); 
                }
            }

            public List<CLSNOVPRD> lisnovedad
            {
                get { return _lisnovedad; }
                set { _lisnovedad = value; base.OnPropertyChanged("lisnovedad"); }
            }

            private ObservableCollection<VMNovedades> _lisnovedades = new ObservableCollection<VMNovedades>();
            public ObservableCollection<VMNovedades> lisnovedades
            {
                get { return _lisnovedades; }
                set { _lisnovedades = value; base.OnPropertyChanged("lisnovedades"); }
            }

            private VMNovedades _selnovedad;
            public VMNovedades selnovedad
            {
                get { return _selnovedad; }
                set { _selnovedad = value; base.OnPropertyChanged("selnovedad"); }
            }

            private Boolean _logValido;
            public Boolean logValido
            {
                get { return _logValido; }
                set { _logValido = value; base.OnPropertyChanged("logValido"); }
            }

            private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
            public MDOgeneral.mensaje msn
            {
                get { return _msn; }
                set { _msn = value; base.OnPropertyChanged("msn"); }
            }

            private string _strTituloVentana;
            public string strTituloVentana
            {
                get { return _strTituloVentana; }
                set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
            }

        #endregion

        #region Comandos
                    
            RelayCommand _cmdSalir;
            public ICommand cmdSalir
            {
                 get
                {
                    if (_cmdSalir == null)
                    {
                        _cmdSalir = new RelayCommand(Salir);
                    }
                    return _cmdSalir;
                }
            }

            RelayCommand _cmdGuardar;
            public ICommand cmdGuardar
            {
                get
                {
                    if (_cmdGuardar == null)
                    {
                        _cmdGuardar = new RelayCommand(r => grabarNovedad());
                    }
                    return _cmdGuardar;
                }
            }

        #endregion

        #region Metodos

            void consultarSemana(string sw)
            {
                try
                {
                    _semana = _repositorio.consultar_Semana(_semana, sw);
                    base.OnPropertyChanged("semana");
                    base.OnPropertyChanged("dtmDesde");
                    base.OnPropertyChanged("dtmHasta");
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void consultarProcesos()
            {
                try
                {
                    procesos = new CLSPRCPRD().listarProcesos();
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void consultarEmpleados()
            {
                try
                {
                    empleados = new CLSMAEEMPP().listaEmpleadosConEquipo(_semana.DESDE_SEM.Year.ToString(), _semana.NROSEM_SEM.ToString());//FJRF - Agregamos la semana y el año
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void consultarNovedad()
            {
                try
                {
                    int numContador = 0;
                    numConsecutivo = _repositorio.consultarConsecutivoNovPesos(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selproceso.CODPRC_PPR, _selempleado.CODEMP_EMP);

                    lisnovedad = _repositorio.consultarNovedad(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selproceso.CODPRC_PPR, _selempleado.CODEMP_EMP, "P", "   ");

                    List<VMNovedades> all = (from nov in lisnovedad select new VMNovedades(nov)).ToList();
                    foreach (VMNovedades nv in all)
                    {
                        numContador = numContador + 1;
                        nv.validarNovedad += ValidateNovedad;
                        nv.PropertyChanged += OnPropertyChanged;
                    }
                    lisnovedades = new ObservableCollection<VMNovedades>(all);
                    lisnovedades.CollectionChanged += OnCollectionChanged;
                    if (numContador == 0)
                        logValido = true;
                    else
                    {
                        if (numConsecutivo == numContador)
                            numConsecutivo=0;
                        else
                            numConsecutivo = numConsecutivo - 1;
                    }

                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                try
                {
                    if (e.NewItems != null && e.NewItems.Count != 0)
                    {
                        //lisnovedades.Last().CONSEC_NVP = (from cust in lisnovedades orderby cust.CONSEC_NVP descending select cust.CONSEC_NVP).First()+numConsecutivo;
                        lisnovedades.Last().CONSEC_NVP = (from cust in lisnovedades select cust).Count() + numConsecutivo;

                        foreach (VMNovedades nov in e.NewItems)
                        {
                            nov.PropertyChanged += OnPropertyChanged;
                        }
                    }

                }
                catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
            }

            void OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
            {
                try
                {
                    logValido = ((from nov in lisnovedades where nov.IsValid.Equals(false) select nov.IsValid).ToList().Count()) > 0 ? true : false;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void ValidateNovedad()
            {
                try
                {
                    logValido = !lisnovedades.Any(x => x.IsValid == false);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            private void grabarNovedad()
            {
                try
                {
                    List<CLSNOVPRD> lstAgregar = (from nov in lisnovedades where nov.agregar.Equals(true) select nov.getNovedades()).ToList();
                    List<CLSNOVPRD> lstActualizar = (from nov in lisnovedades where nov.actualizar.Equals(true) select nov.getNovedades()).ToList();
                    List<CLSNOVPRD> lstEliminar = (from nov in lisnovedades where nov.eliminar.Equals(true) select nov.getNovedades()).ToList();

                    if (_repositorio.guardarNovedades(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selproceso.CODPRC_PPR, _selempleado.CODEMP_EMP, "P", " ", lstActualizar, lstEliminar, lstAgregar))
                    {
                        msn.texto = "La información de novedades se grabo exitosamente.";
                        msn.tipo = true;
                        limpiarNovedades();
                    }
                    else
                    {
                        msn.texto = "La información de novedades no se pudo grabar.";
                        msn.tipo = false;
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void limpiarNovedades()
            {
                try
                {
                    lisnovedades.Clear();
                    selempleado = null;
                    selproceso = null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void Salir(Object frmformulario)
            {
                ((Window)frmformulario).Close();
            }

        #endregion

        #region IDataErrorInfo Members

        string IDataErrorInfo.Error { get { return null; } }

        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }

        #endregion

        #region Validation

        /// <summary>
        /// Returns true if this object has no validation errors.
        /// </summary>
        /// 

        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        static readonly string[] ValidatedProperties = 
            { 
                "semana",
                "dtmDesde",
                "dtmHasta",
                "selproceso",
                "selempleado"
            };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "semana":
                    error = this.ValidateSemana();
                    break;
                case "dtmDesde":
                    error = this.ValidateDesde();
                    break;
                case "dtmHasta":
                    error = this.ValidateHasta();
                    break;
                case "selproceso":
                    error = this.ValidateProceso();
                    break;
                case "selempleado":
                    error = this.ValidateEmpleado();
                    break;
                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }
            return error;
        }

        string ValidateSemana()
        {
            try
            {
                if (semana <= 0 || semana > 52) { return "Debe ingresar una semana valida"; }
                
                return null;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            return null;
        }

        string ValidateDesde()
        {
            try
            {
                if (dtmDesde > dtmHasta) { return "La fecha inicial debe ser menor o igual que la fecha final."; }
                TimeSpan ts = dtmHasta.Subtract(dtmDesde);
                if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }
                
                return null;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            return null;
        }

        string ValidateHasta()
        {
            try
            {
                if (dtmHasta < dtmDesde) { return "La fecha final debe ser mayor o igual que la fecha inicial"; }
                TimeSpan ts = dtmHasta.Subtract(dtmDesde);
                if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }
                
                return null;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            return null;
        }

        string ValidateProceso()
        {
            try
            {
                if (selproceso==null) { return "Debe seleccionar algun proceso."; }

                return null;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            return null;
        }

        string ValidateEmpleado()
        {
            try
            {
                if (selempleado==null) { return "Debe seleccionar algun empleado."; }

                return null;
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            return null;
        }

        #endregion

    }


    public class VMNovedades : ViewModelBase, IDataErrorInfo
    {
        #region Campos

            private CLSNOVPRD _novedades = new CLSNOVPRD();
            private ProcesoProduccionRepositorio _rep = new ProcesoProduccionRepositorio();

        #endregion

        #region Constructor

            public VMNovedades(CLSNOVPRD novedades)
            {
                _novedades = novedades;
            }

            public VMNovedades()
            {
                agregar = true;
            }

        #endregion

        #region Metodos

            public CLSNOVPRD getNovedades()
            {
                return _novedades;
            }

            public delegate void ValidarNovedad();

        #endregion

        #region Interfaces publicas

            public ValidarNovedad validarNovedad { get; set; }    

            public int ANO_NVP
            {
                get { return _novedades.ANO_NVP; }
                set { _novedades.ANO_NVP = value; base.OnPropertyChanged("ANO_NVP"); }
            }

            public int SEM_NVP
            {
                get { return _novedades.SEM_NVP; }
                set 
                { 
                    _novedades.SEM_NVP = value;
                    base.OnPropertyChanged("SEM_NVP");
                }
            }

            public string CODPRC_NVP
            {
                get { return _novedades.CODPRC_NVP; }
                set { _novedades.CODPRC_NVP = value; base.OnPropertyChanged("CODPRC_NVP"); }
            }

            public string CODEMP_NVP
            {
                get { return _novedades.CODEMP_NVP; }
                set { _novedades.CODEMP_NVP = value; base.OnPropertyChanged("CODEMP_NVP"); }
            }

            public int CONSEC_NVP
            {
                get { return _novedades.CONSEC_NVP; }
                set { _novedades.CONSEC_NVP = value; base.OnPropertyChanged("CONSEC_NVP"); }
            }

            public string TIPO_NVP
            {
                get { return _novedades.TIPO_NVP; }
                set { _novedades.TIPO_NVP = value; base.OnPropertyChanged("TIPO_NVP"); }
            }

            public string CONCEP_NVP
            {
                get { return _novedades.CONCEP_NVP; }
                set { _novedades.CONCEP_NVP = value; base.OnPropertyChanged("CONCEP_NVP"); }
            }

            public double VLRNOV_NVP
            {
                get { return _novedades.VLRNOV_NVP; }
                set { _novedades.VLRNOV_NVP = value; base.OnPropertyChanged("VLRNOV_NVP"); }
            }

            public string ESTNOV_NVP
            {
                get { return _novedades.ESTNOV_NVP; }
                set { _novedades.ESTNOV_NVP = value; base.OnPropertyChanged("ESTNOV_NVP"); }
            }

            public string CODCPT_NVP
            {
                get { return _novedades.CODCPT_NVP; }
                set { _novedades.CODCPT_NVP = value; base.OnPropertyChanged("CODCPT_NVP"); }
            }

            private bool _actualizar = false;
            public bool actualizar
            {
                get { return _actualizar; }
                set { _actualizar = value; base.OnPropertyChanged("actualizar"); }
            }

            private bool _eliminar = false;
            public bool eliminar
            {
                get { return _eliminar; }
                set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
            }

            private bool _agregar = false;
            public bool agregar
            {
                get { return _agregar; }
                set { _agregar = value; base.OnPropertyChanged("agregar"); }
            }


        #endregion

        #region IDataErrorInfo Members

            string IDataErrorInfo.Error { get { return null; } }

            string IDataErrorInfo.this[string propertyName]
            {
                get { return this.GetValidationError(propertyName); }
            }

        #endregion

        #region Validation

            /// <summary>
            /// Returns true if this object has no validation errors.
            /// </summary>
            /// 

            public bool IsValid
            {
                get
                {
                    foreach (string property in ValidatedProperties)
                        if (GetValidationError(property) != null)
                            return false;

                    return true;
                }
            }

            static readonly string[] ValidatedProperties = 
                    { 
                        "CONSEC_NVP",
                        "TIPO_NVP",
                        "CONCEP_NVP",
                        "VLRNOV_NVP"
                    };

            string GetValidationError(string propertyName)
            {
                if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                    return null;

                string error = null;

                switch (propertyName)
                {
                    case "CONSEC_NVP":
                        error = this.ValidateCensecutivo();
                        break;
                    case "TIPO_NVP":
                        error = this.ValidateTipo();
                        break;
                    case "CONCEP_NVP":
                        error = this.ValidateConcepto();
                        break;
                    case "VLRNOV_NVP":
                        error = this.ValidateValor();
                        break;
                    default:
                        Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                        break;
                }
                return error;
            }

            string ValidateCensecutivo()
            {
                try
                {
                    if (CONSEC_NVP < 0) { return "Debe ingresar el concecutivo de la noveda."; }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateTipo()
            {
                try
                {
                    if (TIPO_NVP == null) { return "Debe ingresar el tipo. P=Pago o D=Devolución"; }
                    if (TIPO_NVP != null)
                    {
                        if (TIPO_NVP.Trim() != "P" && TIPO_NVP.Trim() != "D") { return "El tipo debe ser P=Pago o D=Devolución"; }
                    }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateConcepto()
            {
                try
                {
                    if (CONCEP_NVP == null) { return "Debe ingresar el concepto de la novedad"; }
                    if (CONCEP_NVP != null)
                    {
                        if (CONCEP_NVP.Length < 5) { return "El concepto de la noveda debe ser mas descripctivo"; }
                    }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateValor()
            {
                try
                {

                    if (VLRNOV_NVP <= 0) { return "El valor de la novedad debe ser mayor que cero"; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

        #endregion
    }
}
